<!DOCTYPE html>
<!--[if lt IE 7]> <html class="no-js lt-ie9 lt-ie8 lt-ie7"> <![endif]-->
<!--[if IE 7]> <html class="no-js lt-ie9 lt-ie8"> <![endif]-->
<!--[if IE 8]> <html class="no-js lt-ie9"> <![endif]-->
<!--[if gt IE 8]><!--> <html class="no-js"> <!--<![endif]-->
<head>
  <meta http-equiv="content-type" content="text/html; charset=utf-8">
  <title>Set  &middot; sitename</title>
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="HandheldFriendly" content="True">
<meta name="MobileOptimized" content="320">
<meta name="viewport" content="width=device-width, initial-scale=1">


<meta name="description" content="Set description" />

<meta name="keywords" content="four, three, ">


<meta property="og:title" content="Set  &middot; sitename ">
<meta property="og:site_name" content="sitename"/>
<meta property="og:url" content="https://lvzongcheng.gitee.io/redis/set/" />
<meta property="og:locale" content="en-EN">


<meta property="og:type" content="article" />
<meta property="og:description" content="Set description"/>
<meta property="og:article:published_time" content="2017-05-13T00:00:00Z" />
<meta property="og:article:modified_time" content="2017-05-13T00:00:00Z" />

  
    
<meta property="og:article:tag" content="four">
    
<meta property="og:article:tag" content="three">
    
  

  

<script type="application/ld+json">
  {
    "@context": "http://schema.org",
    "@type": "Article",
    "headline": "Set",
    "author": {
      "@type": "Person",
      "name": "LvZongCheng"
    },
    "datePublished": "2017-05-13",
    "description": "Set description",
    "wordCount":  406 
  }
</script>



<link rel="canonical" href="https://lvzongcheng.gitee.io/redis/set/" />

<link rel="apple-touch-icon-precomposed" sizes="144x144" href="https://lvzongcheng.gitee.io/touch-icon-144-precomposed.png">
<link href="https://lvzongcheng.gitee.io/favicon.png" rel="icon">

<meta name="generator" content="Hugo 0.60.0" />

  <!--[if lt IE 9]>
<script src="https://oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js"></script>
<script src="https://oss.maxcdn.com/libs/respond.js/1.4.2/respond.min.js"></script>
<![endif]-->

<link href='https://fonts.googleapis.com/css?family=Merriweather:300%7CRaleway%7COpen+Sans' rel='stylesheet' type='text/css'>
<link rel="stylesheet" href="/css/font-awesome.min.css">
<link rel="stylesheet" href="/css/style.css">
<link rel="stylesheet" href="/css/highlight/default.css">

  
  
	<script>
	  (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
	  (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
	  m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
	  })(window,document,'script','//www.google-analytics.com/analytics.js','ga');

	  ga('create', 'Your Google Analytics tracking code', 'auto');
	  ga('send', 'pageview');

	</script>

</head>
<body>
  <main id="main-wrapper" class="container main_wrapper has-sidebar">
    <header id="main-header" class="container main_header">
  <div class="container brand">
  <div class="container title h1-like">
  <a class="baselink" href="https://lvzongcheng.gitee.io">
  LvZongCheng

</a>

</div>

  
<div class="container topline">
  
  淡定 执著 进取 自律


</div>


</div>

  <nav class="container nav primary no-print">
  

<a class="homelink" href="https://lvzongcheng.gitee.io">home</a>


  
<a href="https://lvzongcheng.gitee.io/framework" title="Show list of Frameworks">Frameworks</a>

<a href="https://lvzongcheng.gitee.io/java" title="Show list of Java">Java</a>

<a href="https://lvzongcheng.gitee.io/linux" title="Show list of Linux">Linux</a>

<a href="https://lvzongcheng.gitee.io/redis" title="Show list of Redis">Redis</a>

<a href="https://lvzongcheng.gitee.io/sql" title="Show list of SQL">SQL</a>

<a href="https://lvzongcheng.gitee.io/Spring" title="Show list of Spring">Spring</a>

<a href="https://lvzongcheng.gitee.io/tools" title="Show list of Tools">Tools</a>

<a href="https://lvzongcheng.gitee.io/webpage" title="Show list of WebPage">WebPage</a>

<a href="https://lvzongcheng.gitee.io/information" title="Show list of information">information</a>

<a href="https://lvzongcheng.gitee.io/network" title="Show list of network">network</a>

<a href="https://lvzongcheng.gitee.io/%E5%BE%AE%E6%9C%8D%E5%8A%A1" title="Show list of 微服务">微服务</a>

<a href="https://lvzongcheng.gitee.io/%E6%80%BB%E7%BB%93" title="Show list of 总结">总结</a>

<a href="https://lvzongcheng.gitee.io/%E6%9C%BA%E5%99%A8%E8%87%AA%E5%8A%A8%E5%8C%96" title="Show list of 机器自动化">机器自动化</a>

<a href="https://lvzongcheng.gitee.io/%E6%B1%87%E7%BC%96" title="Show list of 汇编">汇编</a>

<a href="https://lvzongcheng.gitee.io/%E8%AE%B0%E4%BA%8B%E6%9C%AC" title="Show list of 记事本">记事本</a>


</nav>

<div class="container nav secondary no-print">
  
<a id="contact-link-email" class="contact_link" rel="me" aria-label="Email" href="mailto:Lyc19880405@163.com">
  <span class="fa fa-envelope-square"></span></a>



<a id="contact-link-github" class="contact_link" rel="me" aria-label="Github" href="https://github.com/enten/hugo-boilerplate">
  <span class="fa fa-github-square"></span></a>




 


















</div>


  

</header>


<article id="main-content" class="container main_content single">
  <header class="container hat">
  <h1>Set
</h1>

</header>

  <div class="container content">
  <p>一、概述：</p>
<pre><code>  在Redis中，我们可以将Set类型看作为没有排序的字符集合，和List类型一样，我们也可以在该类型的数据值上执行添加、删除或判断某一元素是否存在等操作。需要说明的是，这些操作的时间复杂度为O(1)，即常量时间内完成次操作。Set可包含的最大元素数量是4294967295。
  和List类型不同的是，Set集合中不允许出现重复的元素，这一点和C++标准库中的set容器是完全相同的。换句话说，如果多次添加相同元素，Set中将仅保留该元素的一份拷贝。和List类型相比，Set类型在功能上还存在着一个非常重要的特性，即在服务器端完成多个Sets之间的聚合计算操作，如unions、intersections和differences。由于这些操作均在服务端完成，因此效率极高，而且也节省了大量的网络IO开销。
</code></pre>
<p>二、相关命令列表：</p>
<p>命令原型	时间复杂度	命令描述	返回值
SADD key member [member &hellip;]	 如果在插入的过程用，参数中有的成员在Set中已经存在，该成员将被忽略，而其它成员仍将会被正常插入。如果执行该命令之前，该Key并不存在，该命令将会创建一个新的Set，此后再将参数中的成员陆续插入。如果该Key的Value不是Set类型，该命令将返回相关的错误信息。	本次操作实际插入的成员数量。
SCARD key	 获取Set中成员的数量。	返回Set中成员的数量，如果该Key并不存在，返回0。
SISMEMBER key member	 判断参数中指定成员是否已经存在于与Key相关联的Set集合中。	1表示已经存在，0表示不存在，或该Key本身并不存在。
SMEMBERS key	 获取与该Key关联的Set中所有的成员。返回Set中所有的成员。
Skey 	 随机的移除并返回Set中的某一成员。 由于Set中元素的布局不受外部控制，因此无法像List那样确定哪个元素位于Set的头部或者尾部。	返回移除的成员，如果该Key并不存在，则返回nil。
SREM key member [member &hellip;]	 从与Key关联的Set中删除参数中指定的成员，不存在的参数成员将被忽略，如果该Key并不存在，将视为空Set处理。	从Set中实际移除的成员数量，如果没有则返回0。
SRANDMEMBER key 	 和SPOP一样，随机的返回Set中的一个成员，不同的是该命令并不会删除返回的成员。	返回随机位置的成员，如果Key不存在则返回nil。
SMOVE source destination member	 原子性的将参数中的成员从source键移入到destination键所关联的Set中。因此在某一时刻，该成员或者出现在source中，或者出现在destination中。如果该成员在source中并不存在，该命令将不会再执行任何操作并返回0，否则，该成员将从source移入到destination。如果此时该成员已经在destination中存在，那么该命令仅是将该成员从source中移出。如果和Key关联的Value不是Set，将返回相关的错误信息。	1表示正常移动，0表示source中并不包含参数成员。
SDIFF key [key &hellip;]	 返回参数中第一个Key所关联的Set和其后所有Keys所关联的Sets中成员的差异。如果Key不存在，则视为空Set。	差异结果成员的集合。
SDIFFSTORE destination key [key &hellip;] 	 该命令和SDIFF命令在功能上完全相同，两者之间唯一的差别是SDIFF返回差异的结果成员，而该命令将差异成员存储在destination关联的Set中。如果destination键已经存在，该操作将覆盖它的成员。	返回差异成员的数量。
SINTER key [key &hellip;] 	 该命令将返回参数中所有Keys关联的Sets中成员的交集。因此如果参数中任何一个Key关联的Set为空，或某一Key不存在，那么该命令的结果将为空集。	交集结果成员的集合。
SINTERSTORE destination key [key &hellip;]	 该命令和SINTER命令在功能上完全相同，两者之间唯一的差别是SINTER返回交集的结果成员，而该命令将交集成员存储在destination关联的Set中。如果destination键已经存在，该操作将覆盖它的成员。	返回交集成员的数量。 
SUNION key [key &hellip;] 	 该命令将返回参数中所有Keys关联的Sets中成员的并集。	并集结果成员的集合。
SUNIONSTORE destination key [key &hellip;] 	 该命令和SUNION命令在功能上完全相同，两者之间唯一的差别是SUNION返回并集的结果成员，而该命令将并集成员存储在destination关联的Set中。如果destination键已经存在，该操作将覆盖它的成员。 	返回并集成员的数量。
三、命令示例：</p>
<ol>
<li>SADD/SMEMBERS/SCARD/SISMEMBER:
#在Shell命令行下启动Redis的客户端程序。
/&gt; redis-cli
#插入测试数据，由于该键myset之前并不存在，因此参数中的三个成员都被正常插入。
redis 127.0.0.1:6379&gt; sadd myset a b c
(integer) 3
#由于参数中的a在myset中已经存在，因此本次操作仅仅插入了d和e两个新成员。
redis 127.0.0.1:6379&gt; sadd myset a d e
(integer) 2
#判断a是否已经存在，返回值为1表示存在。
redis 127.0.0.1:6379&gt; sismember myset a
(integer) 1
#判断f是否已经存在，返回值为0表示不存在。
redis 127.0.0.1:6379&gt; sismember myset f
(integer) 0
#通过smembers命令查看插入的结果，从结果可以，输出的顺序和插入顺序无关。
redis 127.0.0.1:6379&gt; smembers myset
1) &ldquo;c&rdquo;
2) &ldquo;d&rdquo;
3) &ldquo;a&rdquo;
4) &ldquo;b&rdquo;
5) &ldquo;e&rdquo;
#获取Set集合中元素的数量。
redis 127.0.0.1:6379&gt; scard myset
(integer) 5</li>
</ol>
<pre><code>2. SPOP/SREM/SRANDMEMBER/SMOVE:
#删除该键，便于后面的测试。
redis 127.0.0.1:6379&gt; del myset
(integer) 1
#为后面的示例准备测试数据。
redis 127.0.0.1:6379&gt; sadd myset a b c d
(integer) 4
#查看Set中成员的位置。
redis 127.0.0.1:6379&gt; smembers myset
1) &quot;c&quot;
2) &quot;d&quot;
3) &quot;a&quot;
4) &quot;b&quot;
#从结果可以看出，该命令确实是随机的返回了某一成员。
redis 127.0.0.1:6379&gt; srandmember myset
&quot;c&quot;
#Set中尾部的成员b被移出并返回，事实上b并不是之前插入的第一个或最后一个成员。
redis 127.0.0.1:6379&gt; spop myset
&quot;b&quot;
#查看移出后Set的成员信息。
redis 127.0.0.1:6379&gt; smembers myset
1) &quot;c&quot;
2) &quot;d&quot;
3) &quot;a&quot;
#从Set中移出a、d和f三个成员，其中f并不存在，因此只有a和d两个成员被移出，返回为2。
redis 127.0.0.1:6379&gt; srem myset a d f
(integer) 2
#查看移出后的输出结果。
redis 127.0.0.1:6379&gt; smembers myset
1) &quot;c&quot;
#为后面的smove命令准备数据。
redis 127.0.0.1:6379&gt; sadd myset a b
(integer) 2
redis 127.0.0.1:6379&gt; sadd myset2 c d
(integer) 2
#将a从myset移到myset2，从结果可以看出移动成功。
redis 127.0.0.1:6379&gt; smove myset myset2 a
(integer) 1
#再次将a从myset移到myset2，由于此时a已经不是myset的成员了，因此移动失败并返回0。
redis 127.0.0.1:6379&gt; smove myset myset2 a
(integer) 0
#分别查看myset和myset2的成员，确认移动是否真的成功。
redis 127.0.0.1:6379&gt; smembers myset
1) &quot;b&quot;
redis 127.0.0.1:6379&gt; smembers myset2
1) &quot;c&quot;
2) &quot;d&quot;
3) &quot;a&quot;
</code></pre>
<ol start="3">
<li>SDIFF/SDIFFSTORE/SINTER/SINTERSTORE:
#为后面的命令准备测试数据。
redis 127.0.0.1:6379&gt; sadd myset a b c d
(integer) 4
redis 127.0.0.1:6379&gt; sadd myset2 c
(integer) 1
redis 127.0.0.1:6379&gt; sadd myset3 a c e
(integer) 3
#myset和myset2相比，a、b和d三个成员是两者之间的差异成员。再用这个结果继续和myset3进行差异比较，b和d是myset3不存在的成员。
redis 127.0.0.1:6379&gt; sdiff myset myset2 myset3
1) &ldquo;d&rdquo;
2) &ldquo;b&rdquo;
#将3个集合的差异成员存在在diffkey关联的Set中，并返回插入的成员数量。
redis 127.0.0.1:6379&gt; sdiffstore diffkey myset myset2 myset3
(integer) 2
#查看一下sdiffstore的操作结果。
redis 127.0.0.1:6379&gt; smembers diffkey
1) &ldquo;d&rdquo;
2) &ldquo;b&rdquo;
#从之前准备的数据就可以看出，这三个Set的成员交集只有c。
redis 127.0.0.1:6379&gt; sinter myset myset2 myset3
1) &ldquo;c&rdquo;
#将3个集合中的交集成员存储到与interkey关联的Set中，并返回交集成员的数量。
redis 127.0.0.1:6379&gt; sinterstore interkey myset myset2 myset3
(integer) 1
#查看一下sinterstore的操作结果。
redis 127.0.0.1:6379&gt; smembers interkey
1) &ldquo;c&rdquo;
#获取3个集合中的成员的并集。 <br>
redis 127.0.0.1:6379&gt; sunion myset myset2 myset3
1) &ldquo;b&rdquo;
2) &ldquo;c&rdquo;
3) &ldquo;d&rdquo;
4) &ldquo;e&rdquo;
5) &ldquo;a&rdquo;
#将3个集合中成员的并集存储到unionkey关联的set中，并返回并集成员的数量。
redis 127.0.0.1:6379&gt; sunionstore unionkey myset myset2 myset3
(integer) 5
#查看一下suiionstore的操作结果。
redis 127.0.0.1:6379&gt; smembers unionkey
1) &ldquo;b&rdquo;
2) &ldquo;c&rdquo;
3) &ldquo;d&rdquo;
4) &ldquo;e&rdquo;
5) &ldquo;a&rdquo;</li>
</ol>
<p>四、应用范围：</p>
<pre><code>  1). 可以使用Redis的Set数据类型跟踪一些唯一性数据，比如访问某一博客的唯一IP地址信息。对于此场景，我们仅需在每次访问该博客时将访问者的IP存入Redis中，Set数据类型会自动保证IP地址的唯一性。
  2). 充分利用Set类型的服务端聚合操作方便、高效的特性，可以用于维护数据对象之间的关联关系。比如所有购买某一电子设备的客户ID被存储在一个指定的Set中，而购买另外一种电子产品的客户ID被存储在另外一个Set中，如果此时我们想获取有哪些客户同时购买了这两种商品时，Set的intersections命令就可以充分发挥它的方便和效率的优势了。
</code></pre>

</div>


  
</article>
      <footer id="main-footer" class="container main_footer">
  

  <div class="container nav foot no-print">
  
<a href="https://lvzongcheng.gitee.io/license">license</a>


  <a class="toplink" href="#">back to top</a>

</div>

  <div class="container credits">
  
<div class="container footline">
  
  code with <!-- raw HTML omitted --><!-- raw HTML omitted -->


</div>


  
<div class="container copyright">
  
  (c) 2015 yourname.


</div>


</div>

</footer>

    </main>
    
<script type="text/javascript">
  (function() {
    
    
    if (window.location.hostname == "localhost")
      return;
    var dsq = document.createElement('script'); dsq.async = true; dsq.type = 'text/javascript';
    dsq.src = '//your_disqus_shortname.disqus.com/count.js';
    (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(dsq);
  })();
</script>



<script src="/js/highlight.pack.js"></script>
<script>hljs.initHighlightingOnLoad();</script>



    
  </body>
</html>

